<template>
    <MainContent :bodyStyle="{
        padding: 0
    }">
        <template #headerRight>
            <div class="header-right-btn header-right-btn-json" @click="setJson" title="导入JSON">
                <DynamicIcon :icon="'SvgIconImportFile'" />
            </div>
            <div class="header-right-btn header-right-btn-json" @click="setOption" title="导入Options">
                <DynamicIcon :icon="'SvgIconImportCode'" />
            </div>
            <div class="header-right-btn header-right-btn-json" @click="showJson" title="生成JSON">
                <DynamicIcon :icon="'SvgIconJson'" />
            </div>
            <div class="header-right-btn header-right-btn-opt" @click="showOption" title="生成Options">
                <DynamicIcon :icon="'SvgIconCode'" />
            </div>
            <div class="header-right-btn header-right-btn-tpl" @click="showTemplate" title="生成组件">
                <DynamicIcon :icon="'SvgIconTpl'" />
            </div>
            <div class="header-right-btn header-right-btn-locale" @click="changeLocale" title="中英切换">
                <DynamicIcon :icon="lang == 'cn' ? 'SvgIconZh' : 'SvgIconEn'" />
            </div>
        </template>
        <div class="desktop-container">
            <form-designer ref="designerRef" :locale="locale" />
            <el-dialog :title="title[type]" v-model="state" class="form-create-editor-dialog">
                <div ref="editorRef" v-if="state"></div>
                <span style="color: var(--el-color-danger)" v-if="err">输入内容格式有误!</span>
                <template #footer v-if="type > 2">
                    <span slot="footer" class="dialog-footer">
                        <el-button @click="state = false" size="small">取 消</el-button>
                        <el-button type="primary" @click="onOk" size="small">确 定</el-button>
                    </span>
                </template>
            </el-dialog>
        </div>
    </MainContent>
</template>

<script setup lang="ts">
import { onMounted, ref, watch, nextTick } from 'vue';

import ZhCn from '../../locale/zh-cn'
import En from '../../locale/en'
// @ts-ignore
import jsonlint from 'jsonlint-mod'
import 'codemirror/lib/codemirror.css'
import 'codemirror/addon/lint/lint.css'
// @ts-ignore
import CodeMirror from 'codemirror/lib/codemirror'
import 'codemirror/addon/lint/lint'
import 'codemirror/addon/lint/json-lint'
import 'codemirror/mode/javascript/javascript'
import 'codemirror/mode/vue/vue'
import 'codemirror/mode/xml/xml'
import 'codemirror/mode/css/css'
import 'codemirror/addon/mode/overlay'
import 'codemirror/addon/mode/simple'
import 'codemirror/addon/selection/selection-pointer'
import 'codemirror/mode/handlebars/handlebars'
import 'codemirror/mode/htmlmixed/htmlmixed'
import 'codemirror/mode/pug/pug'
// @ts-ignore
import is from '@form-create/utils/lib/type'
import formCreate from '@form-create/element-ui'


const locale = ref<any>(null)
const lang = ref<string>('cn')
const title = ref(['生成规则', '表单规则', '生成组件', '设置生成规则', '设置表单规则'])
const state = ref(false)
const value = ref<any>(null)
const editor = ref<any>(null)
const err = ref(false)
const type = ref(-1)
const editorRef = ref()
const designerRef = ref()

const changeLocale = () => {
    if (lang.value === 'cn') {
        locale.value = En
        lang.value = 'en'
    } else {
        locale.value = ZhCn
        lang.value = 'cn'
    }
}

const load = () => {
    let val: any = null;
    if (type.value === 2) {
        val = value.value
    } else if (type.value === 0) {
        val = formCreate.toJson(value.value, 2)
    } else {
        val = JSON.stringify(value.value, null, 2)
    }
    nextTick(() => {
        editor.value = CodeMirror(editorRef.value, {
            lineNumbers: true,
            mode: type.value === 2 ? { name: 'vue' } : 'application/json',
            gutters: ['CodeMirror-lint-markers'],
            // lint: true,
            line: true,
            tabSize: 2,
            lineWrapping: true,
            value: val || ''
        })
    })
}

const onValidationError = (e: any) => {
    err.value = e.length !== 0
}

const showJson = () => {
    state.value = true
    type.value = 0
    value.value = designerRef.value.getRule()
}

const showOption = () => {
    state.value = true
    type.value = 1
    value.value = designerRef.value.getOption()
}

const showTemplate = () => {
    state.value = true
    type.value = 2
    value.value = makeTemplate()
}
const setJson = () => {
    state.value = true
    type.value = 3
    value.value = []
}

const setOption = () => {
    state.value = true
    type.value = 4
    value.value = { form: {} }
}

const onOk = () => {
    if (err.value) return
    const json = editor.value.getValue()
    let val = JSON.parse(json)
    if (type.value === 3) {
        if (!Array.isArray(val)) {
            err.value = true
            return
        }
        designerRef.value.setRule(formCreate.parseJson(json))
    } else {
        if (!is.Object(val) || !val.form) {
            err.value = true
            return
        }
        designerRef.value.setOption(val)
    }
    state.value = false
}

const makeTemplate = () => {
    const rule = designerRef.value.getRule()
    const opt = designerRef.value.getOption()
    return `<template>
              <form-create
                v-model="fapi"
                :rule="rule"
                :option="option"
                @submit="onSubmit"
               ></form-create>
            </template>

            <script setup lang="ts">
            import { onMounted, ref, watch,nextTick } from 'vue';
            import formCreate from "@form-create/element-ui";

            const fapi = ref<any>(null)
            const rule = ref(formCreate.parseJson('${formCreate.toJson(rule).replaceAll('\\', '\\\\')}'))
            const option = ref(formCreate.parseJson('${JSON.stringify(opt)}'))

            const onSubmit =(formData:any)=> {
                   //todo 提交表单
            }
           <\/script>
`
}

watch(
    (): boolean => state.value,
    (newVal: boolean): void => {
        if (!newVal) {
            value.value = null
            err.value = false
        }
    },
    {
        immediate: true,
        deep: false
    }
)

watch(
    (): any => value.value,
    (newVal: any): void => {
        load()
    },
    {
        immediate: true,
        deep: false
    }
)


onMounted(() => {
    const win: any = window
    win.jsonlint = jsonlint
})

</script>

<style scoped lang="scss">
.header-right-btn {
    box-sizing: border-box;
    font-size: 14px;
    cursor: pointer;
    transition: 0.35s;
    height: calc(var(--main-content-header-height) - 15px);
    width: calc(var(--main-content-header-height) - 15px);
    display: flex;
    justify-content: center;
    align-items: center;
    color: var(--main-content-header-btn-color);
    margin-left: 5px;
    border-radius: 4px;
}

.header-right-btn-json {
    font-size: 11px;

    &:hover {
        background-color: var(--el-color-info-light-5);
    }
}


.header-right-btn-opt {
    font-size: 11px;

    &:hover {
        background-color: var(--el-color-primary);
        color: var(--el-color-white);
    }
}

.header-right-btn-tpl {
    font-size: 11px;

    &:hover {
        background-color: var(--el-color-success);
        color: var(--el-color-white);
    }
}

.header-right-btn-locale {
    font-size: 11px;

    &:hover {
        background-color: var(--el-color-info);
        color: var(--el-color-white);
    }
}
</style>